x64: lower isub by a constant to lea - #14015
Conversation
8888063 to
39c2a52
Compare
|
Pushed a fixup: refreshed the 12 |
Subscribe to Label ActionDetailsThis issue or pull request has been labeled: "cranelift", "cranelift:area:x64", "isle"Thus the following users have been cc'd because of the following labels:
To subscribe or unsubscribe from this label, edit the |
|
Hi @darmie -- are you aware of the add-vs-lea performance discussion thread we had recently (#13325)? I ask because at the very least, we should benchmark this change with the full Sightglass suite. I am also pretty leery in general of introducing more uses of LEA given the performance variability that we've seen on different systems. I'm not surprised that you saw a speedup on one particular benchmark since LEA is "non-destructive" (doesn't clobber the source) but I'd be curious to know how this looks overall. Thanks! |
|
Hi @cfallin! Actually I am not aware of that thread, I should have searched first. Yes I saw a performance improvement on my alderlake x86_64 box, but it's only ~6.9% so far. I'll read through the thread now. |
`iadd` of a value and a constant already lowers to `lea`, folding the constant into the address displacement and avoiding a register copy when the result lands in a different register than the input. `isub` by a constant did not: it fell to the two-operand `sub`, which forces a `mov`+`sub` pair whenever the destination differs from the source. Lower `x - C` to `lea -C(x)` for 32- and 64-bit types, mirroring the `iadd` path. The rule fires only when the negated constant fits in an `Offset32` (i.e. `C` is not `i32::MIN`); register/register `isub` is unchanged.
- Precise-output filetest asserting `x - C` lowers to a single `lea`, and that register/register `isub` still lowers to `sub`. - Runtest exercising the result on the interpreter and every native target. - Refresh the `load-store/x64` disas goldens: the in-place bounds-check `sub $C` now lowers via `lea` to `add $-C`, identical to how `iadd` by a constant already lowers (same instruction count).
39c2a52 to
10bdb3b
Compare
|
@cfallin I have gone through the thread. From what I gather, |
|
We discussed this in the other thread a bit but we don't have per-microarchitecture machine models, and that is what it'd take (which is a really big project in the compiler). We don't want to have a patchwork of heuristics for things like this. Can you clarify
do you mean on all of Sightglass, or on one particular benchmark? |
It's a microbench I did for my project. I simply did multiple A/B runs – that was how I arrived at that score. |
|
OK, I think we'd want Sightglass runs across multiple microarchitectures that show clear benefit here before deciding to take it for sure. |
Yes I can do fhat. Is the Sightglass tool setup in the CI? |
|
It's not in CI -- see the README at https://github.com/bytecodealliance/sightglass/ for more. |
Oh.. thanks! |
|
Sightglass results. The short version: this rule is a wash and I think it should be closed, but the run turned up something more interesting than the PR, so I want to put both in front of you. Setup: wasmtime This PR: no aggregate movement. Sum total across the suite is "no difference" for execution and compilation. Per benchmark, reproducing across both passes: The rule fires heavily, so this is not a case of the suite failing to exercise it. AOT-compiling for x86_64 and counting mnemonics, The more useful result. To find out whether that was LEA being weak here or just this rule being marginal, I ran the counterfactual from #13325 on the same rig: main, with
The wins are significant: That also explains why my rule is a wash while the Given that, I don't think there's a case for this change and I'm happy to close it. If it's useful I can push the no- |
Hi @darmie -- this response looks like it is a direct copy/paste out of an AI session, complete with a suggestion to run a slash-command. Aside from not making sense in context (it makes no sense to tell me I can run a slash-command here in a GitHub thread -- it only made sense in your agent chat), this is a direct violation of our AI tool policy, which states that you cannot use an LLM's output directly in correspondence with other humans. You yourself may use such tools, but must review the output yourself, and correspond as a human with other humans. While we appreciate contributions, we want to mentor and collaborate with people, not indirectly with their AI bots through a lossy channel. Please make sure you adhere to this policy in any future contributions. Given the technical data, as well as this policy violation issue (and the implication that you have not deeply understood the issue yourself but are directly copy/pasting from a bot in the thread), I will go ahead and close this PR. Thanks. |
@cfallin I apologize that it still reads that way even though it has been reviewed and edited by me. Yes I did use AI to gather my thoughts, but between the day you asked me to use Sightglass tool and now, I had run the benchmarks many times partly in hopes to justify this PR, but to give a clear verdict on where it stands. I am fully aware of the policy and I did honestly considered that while I also tried not to remove relevant information that you may find useful. |
iaddof a value and a 32/64-bit constant already lowers tolea, foldingthe constant into the address displacement and computing the result in a
different register than the input without a separate
mov.isubby aconstant did not have a matching rule: it fell through to the two-operand
sub, which forces amov+subpair whenever the destination registerdiffers from the source.
This adds a rule that lowers
x - C(for a 32- or 64-bit integer constantC) tolea -C(x), mirroring the existingiaddpath. The rule fires onlywhen the negated constant fits in an
Offset32(i.e.Cis noti32::MIN);register/register
isubis unchanged.Example
Before:
After:
One instruction instead of two, and no flags clobbered.
Testing
isub-const-lea.clif) asserting thelealowering for i64 and i32, and that register/register
isubstill lowersto
sub.x - C(including a negative constant) on theinterpreter and every native target.
isa/x64filetests pass unchanged.I found this while profiling a call/arithmetic-heavy workload where every
argument setup was an
x - C; folding themovaway was a measurable win.